package com.lhd.qd.common.handler;

import com.lhd.qd.common.consts.CommonConsts;
import com.lhd.qd.common.util.TokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 认证
 */
@Slf4j
@WebFilter(urlPatterns = {"/*"})
public class AuthenticationFilter implements Filter {

    private static final String[] AUTH_WHITE_LIST = {
            "/",
            "/login", "/logout",
            "/favicon.ico",
            "/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/v2/api-docs", "/csrf",
            "/ws/**"
    };

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        if (isNeedAuth(request.getRequestURI())) {
            try {

                TokenUtils.verify(request.getHeader(CommonConsts.REQUEST_HEADER_TOKEN_KEY));
            }
            catch (Exception e) {
                log.debug("认证异常", e);
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
                return;
            }
        }

        filterChain.doFilter(servletRequest, servletResponse);
    }

    private boolean isNeedAuth(String requestUri) {

        if (requestUri.length() > 1 && requestUri.endsWith("/")) {
            requestUri = requestUri.substring(0, requestUri.length() - 1);
        }

        for (String uri : AUTH_WHITE_LIST) {
            if (isMatch(requestUri, uri)) {
                return false;
            }
        }
        return true;
    }

    private boolean isMatch(String requestUri, String whiteListUri) {

        Boolean isEqual = requestUri.equals(whiteListUri);
        Boolean isLike = whiteListUri.contains("/**") && requestUri.startsWith(whiteListUri.replace("/**", ""));

        return isEqual || isLike;
    }
}
